<html>
<head><meta charset="utf-8"><title>layout optimization in stable? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html">layout optimization in stable?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="213473537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473537">(Oct 15 2020 at 19:09)</a>:</h4>
<p>What are the blockers for having stable layout optimizations? Is it just a question of "what syntax and semantics are we prepared to commit to", or is there some more fundamental issue?</p>



<a name="213473639"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473639" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473639">(Oct 15 2020 at 19:10)</a>:</h4>
<p>If we added a simplified niche-specification syntax, would that be something that could potentially be stabilized?</p>



<a name="213473655"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473655" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473655">(Oct 15 2020 at 19:10)</a>:</h4>
<p>my knowledge is that we may want to use const generics for this, so it would be blocked on that</p>



<a name="213473701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473701">(Oct 15 2020 at 19:10)</a>:</h4>
<p>That's what I meant by "simplified": is there some reason that the simple version <em>needs</em> const generics?</p>



<a name="213473727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473727">(Oct 15 2020 at 19:11)</a>:</h4>
<p>I personally don't think we should stabilize something like the current attributes used in the compiler</p>



<a name="213473835"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473835" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473835">(Oct 15 2020 at 19:11)</a>:</h4>
<p>as they will become outdated in a few years, but I also don't value this feature too highly so it seems fine to me to wait a bit here.</p>



<a name="213473921"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213473921" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213473921">(Oct 15 2020 at 19:12)</a>:</h4>
<p>When you mention using const generics for this, do you mean creating new types to define this, or do you mean providing a way to specify this for user-defined types using const generics?</p>



<a name="213474016"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474016" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474016">(Oct 15 2020 at 19:13)</a>:</h4>
<p>I previously quickly mentioned this in <a href="#narrow/stream/122651-general/topic/NonZero*.20layout.20optimization/near/213445435">https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/NonZero*.20layout.20optimization/near/213445435</a></p>



<a name="213474048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474048">(Oct 15 2020 at 19:13)</a>:</h4>
<p>but I am thinking of adding newtype wrappers for the basic integers</p>



<a name="213474080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474080">(Oct 15 2020 at 19:13)</a>:</h4>
<p>so user defined types can then be built using these newtypes</p>



<a name="213474232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474232">(Oct 15 2020 at 19:14)</a>:</h4>
<p>That would certainly be helpful, but I'm wondering if that needs to be the <em>only</em> stable interface to niches.</p>



<a name="213474480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474480">(Oct 15 2020 at 19:16)</a>:</h4>
<p>The whole "start" and "end" mechanism for valid ranges doesn't seem like the mechanism we should stabilize, but I'm wondering if a "mask/bits" pattern would be reasonable.</p>



<a name="213474677"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474677" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474677">(Oct 15 2020 at 19:18)</a>:</h4>
<p>Straw syntax, semantics are the important bit here: <code>#[valid_values(mask=0b111, valid=0)]</code> would say "this must be a multiple of 8".</p>



<a name="213474734"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213474734" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213474734">(Oct 15 2020 at 19:18)</a>:</h4>
<p><code>mask</code> would be optional and default to the size of the type, and you could specify either <code>valid</code> or <code>invalid</code>.</p>



<a name="213475002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213475002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213475002">(Oct 15 2020 at 19:21)</a>:</h4>
<p>This would <em>benefit</em> from const generics, in that it'd be nice to use const generics and const evaluation for the mask and valid/invalid values, but initially it could just accept literals.</p>



<a name="213475571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213475571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213475571">(Oct 15 2020 at 19:25)</a>:</h4>
<p>This would work for aligned pointers, or floats with NaN-boxing, or Linux-kernel-style "valid pointers can't be -1 to -4095 so you can return pointer-or-negative-errno"...</p>



<a name="213475696"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213475696" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213475696">(Oct 15 2020 at 19:26)</a>:</h4>
<p>I believe the compiler currently has no way of optimizing within the compiler on e.g. aligned pointers due to lack of "I will never take a reference to this"</p>



<a name="213475758"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213475758" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213475758">(Oct 15 2020 at 19:27)</a>:</h4>
<p>we need invalid values, not bit-ranges, in some sense</p>



<a name="213475990"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213475990" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213475990">(Oct 15 2020 at 19:28)</a>:</h4>
<p>yeah the layout code currently just tracks an invalid range of values for each type (and its position)</p>



<a name="213476034"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476034" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476034">(Oct 15 2020 at 19:29)</a>:</h4>
<p>it tracks only the largest niche</p>



<a name="213476129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476129">(Oct 15 2020 at 19:29)</a>:</h4>
<p>we <em>could</em> use alignment to get a slightly larger niche though (if we don't already)</p>



<a name="213476284"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476284" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476284">(Oct 15 2020 at 19:30)</a>:</h4>
<p>I know that's what the compiler currently takes advantage of. In theory, we don't need "I will never take a reference" to be able to optimize further; we could alternatively just rely on people not caring what enum discriminants are, and do global optimization. :)</p>



<a name="213476383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476383">(Oct 15 2020 at 19:31)</a>:</h4>
<p>For that, you don't need "I will never take a reference", just "I will never care about the exact bit pattern".</p>



<a name="213476468"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476468" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476468">(Oct 15 2020 at 19:32)</a>:</h4>
<p>(That said, "I will never take a reference" would be useful anyway, for things like packed structs, so having it seems like a good idea.)</p>



<a name="213476554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476554">(Oct 15 2020 at 19:33)</a>:</h4>
<p>I think what I'm wondering is whether it'd be unreasonable to add a mechanism that gives us more information than we can <em>currently</em> use.</p>



<a name="213476574"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213476574" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213476574">(Oct 15 2020 at 19:33)</a>:</h4>
<p>The current attributes give us <em>exactly</em> as much information as we can use.</p>



<a name="213483001"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213483001" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213483001">(Oct 15 2020 at 20:29)</a>:</h4>
<p>How would you do range based validity with this? Like an enum that only goes up to 42</p>



<a name="213483289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213483289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213483289">(Oct 15 2020 at 20:31)</a>:</h4>
<p>How about being able to say "<code>a..b</code> are valid/invalid" with some precedence order</p>



<a name="213484470"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213484470" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213484470">(Oct 15 2020 at 20:40)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> Sorry, my syntax straw-proposal was a little unclear on that front. I intended for valid and invalid to accept ranges, not just single values, but I didn't give any examples to that effect.</p>



<a name="213484576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213484576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213484576">(Oct 15 2020 at 20:41)</a>:</h4>
<p>Oh, my impression was that the ranges in your proposal are of the form e.g. <code>0b1011xx1x0</code></p>



<a name="213484613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213484613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213484613">(Oct 15 2020 at 20:41)</a>:</h4>
<p>or do you mean something else by "mask"?</p>



<a name="213484807"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213484807" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213484807">(Oct 15 2020 at 20:42)</a>:</h4>
<p>of course, it is also annoying to specify a mask pattern like that as a range, although I don't know if there are any anticipated uses for it</p>



<a name="213484827"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213484827" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213484827">(Oct 15 2020 at 20:42)</a>:</h4>
<p>Masks would be numbers (<code>0b</code> or <code>0x</code> syntax typically, though not required) where the 1 bits select the value bits relevant for valid/invalid.</p>



<a name="213484906"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213484906" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213484906">(Oct 15 2020 at 20:43)</a>:</h4>
<p>And you're right, that syntax isn't ideal to specify ranges.</p>



<a name="213485031"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485031" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485031">(Oct 15 2020 at 20:44)</a>:</h4>
<p>you could have <code>valid(...)</code> and <code>invalid(...)</code> attrs to make it more ergonomic</p>



<a name="213485105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485105">(Oct 15 2020 at 20:45)</a>:</h4>
<p>True.</p>



<a name="213485108"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485108" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485108">(Oct 15 2020 at 20:45)</a>:</h4>
<p>and also have the default interpretation of bits not covered by a range be the opposite of the first specified range</p>



<a name="213485250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485250">(Oct 15 2020 at 20:46)</a>:</h4>
<p>so that <code>#[valid(a..b)]</code> and <code>#[invalid(a..b)]</code> are opposites when alone on a type decl</p>



<a name="213485252"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485252" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485252">(Oct 15 2020 at 20:46)</a>:</h4>
<p>I'd change "first specified range" to "previous specified range for those bits", but otherwise, yeah.</p>



<a name="213485382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485382">(Oct 15 2020 at 20:47)</a>:</h4>
<p>Not that this is likely, but that would allow <code>#[valid(1..=10)] #[invalid(2..=9)] #[valid(3..=8)]</code>, which would mean that valid values are <code>1, 3, 4, 5, 6, 7, 8, 10</code>.</p>



<a name="213485465"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485465" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485465">(Oct 15 2020 at 20:47)</a>:</h4>
<p>Thinking about it, I think "valid/invalid ranges with optional masks, applied sequentially in the order specified " would suffice for most cases.</p>



<a name="213485727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485727">(Oct 15 2020 at 20:49)</a>:</h4>
<p>I think of it as a decision tree,</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">if</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..=</span><span class="mi">10</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">2</span><span class="o">..=</span><span class="mi">9</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="mi">3</span><span class="o">..=</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">      </span><span class="kc">true</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>where the last <code>false</code> is <code>false</code> because the first range in the list was a <code>valid</code></p>



<a name="213485805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485805">(Oct 15 2020 at 20:50)</a>:</h4>
<p>Ah, I see!</p>



<a name="213485842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485842">(Oct 15 2020 at 20:50)</a>:</h4>
<p>Yeah, I think we're saying the same thing, except that you're also explicitly stating what the top-level implicit default is, which is good to specify. :)</p>



<a name="213485930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485930">(Oct 15 2020 at 20:51)</a>:</h4>
<p>When you said "bits not covered by a range", I was thinking you meant "not covered by one of the ranges", but I think you meant "bits not covered by <em>any</em> range"?</p>



<a name="213485949"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213485949" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213485949">(Oct 15 2020 at 20:51)</a>:</h4>
<p>yes</p>



<a name="213486038"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486038" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486038">(Oct 15 2020 at 20:52)</a>:</h4>
<p>Then I agree. If your first attribute is <code>valid</code> then unspecified bits are invalid; if your first attribute is <code>invalid</code> then unspecified bits are valid.</p>



<a name="213486327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486327">(Oct 15 2020 at 20:54)</a>:</h4>
<p>actually I think it needs to cascade the other way around,</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">if</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">3</span><span class="o">..=</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kc">true</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">2</span><span class="o">..=</span><span class="mi">9</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kc">false</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..=</span><span class="mi">10</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kc">true</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kc">false</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="213486364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486364">(Oct 15 2020 at 20:54)</a>:</h4>
<p>so that later patterns take precedence</p>



<a name="213486416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486416">(Oct 15 2020 at 20:55)</a>:</h4>
<p>otherwise it only works when the ranges nest</p>



<a name="213486565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486565">(Oct 15 2020 at 20:56)</a>:</h4>
<p>I'm not sure how your masking works though</p>



<a name="213486826"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486826" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486826">(Oct 15 2020 at 20:57)</a>:</h4>
<p>(Right. The original was hard to read because of the formatting, and I didn't go back and look at it again after it was formatted. ;) )</p>



<a name="213486969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213486969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213486969">(Oct 15 2020 at 20:58)</a>:</h4>
<p>Masks would be applied to a value before testing its range.</p>



<a name="213487033"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213487033" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213487033">(Oct 15 2020 at 20:59)</a>:</h4>
<p><code>#[valid(range, mask=m)]</code> would become <code>if x &amp; m in range</code>.</p>



<a name="213487091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213487091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213487091">(Oct 15 2020 at 21:00)</a>:</h4>
<p>(so would <code>invalid</code>, just with a <code>false</code> inside the if body rather than a <code>true</code>. :) )</p>



<a name="213487318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213487318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213487318">(Oct 15 2020 at 21:01)</a>:</h4>
<p>oh I see, each clause does both jobs</p>



<a name="213487534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213487534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213487534">(Oct 15 2020 at 21:03)</a>:</h4>
<p>That looks pretty flexible to me, and as long as the easy cases are easy people probably don't have to learn the general case</p>



<a name="213487715"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213487715" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213487715">(Oct 15 2020 at 21:04)</a>:</h4>
<p>although you have invented an interesting CS problem: find the largest contiguous niche in a validity predicate so defined. :)</p>



<a name="213489448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213489448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213489448">(Oct 15 2020 at 21:20)</a>:</h4>
<p>We were recently talking about a use case for this in Fuchsia. Our syscall return codes are <code>i32</code>s and we were thinking of reserving half of that range for application level errors. I'd love to be able to do that while using idiomatic Rust ADTs.</p>



<a name="213490590"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213490590" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213490590">(Oct 15 2020 at 21:32)</a>:</h4>
<p><span class="user-mention" data-user-id="116883">@tmandry</span> Does Fuschia always return <code>i32</code> on all platforms, even 64-bit ones?</p>



<a name="213491133"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491133" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491133">(Oct 15 2020 at 21:37)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> yes</p>



<a name="213491198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491198">(Oct 15 2020 at 21:37)</a>:</h4>
<p>Is it <em>always</em> an error code, never "file descriptor or error" or similar?</p>



<a name="213491364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491364">(Oct 15 2020 at 21:39)</a>:</h4>
<p>well the return value is a 32-bit error code, and we use out params for things like file descriptors (everything is a handle on fuchsia)</p>



<a name="213491392"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491392" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491392">(Oct 15 2020 at 21:39)</a>:</h4>
<p>e.g. <a href="https://fuchsia.dev/fuchsia-src/reference/syscalls/handle_duplicate">zx_handle_duplicate</a></p>



<a name="213491529"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491529" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491529">(Oct 15 2020 at 21:40)</a>:</h4>
<p>if you're curious, here are <a href="https://fuchsia-docs.firebaseapp.com/rust/fuchsia_zircon/index.html">docs for our idiomatic Rust wrapper</a></p>



<a name="213491598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491598">(Oct 15 2020 at 21:41)</a>:</h4>
<p>Awesome. Thanks for doing the sensible thing. :)</p>



<a name="213491624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213491624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213491624">(Oct 15 2020 at 21:41)</a>:</h4>
<p>sure but I can't take credit for it :)</p>



<a name="213496981"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213496981" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213496981">(Oct 15 2020 at 22:42)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> I think the question can be split as well -- we could offer restricted-validity types while still leaving any layout optimizations as not guaranteed.</p>



<a name="213497037"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213497037" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213497037">(Oct 15 2020 at 22:42)</a>:</h4>
<p>I think a big part of why we haven't looked at it yet, though, is that the first thing everyone always wants with this is <code>Integer&lt;MIN, MAX&gt;</code>.</p>



<a name="213497147"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213497147" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213497147">(Oct 15 2020 at 22:44)</a>:</h4>
<p>This gets to that same conversation we had about alignment, and how it's a bit weird for the attributes to be reading const generic parameters that aren't actually defined yet.</p>



<a name="213526381"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213526381" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213526381">(Oct 16 2020 at 07:27)</a>:</h4>
<p>I don't think we should promise any niche optimizations, because it should be possible for a compliant rust compiler to not support them or choose not to e.g. from a flag</p>



<a name="213526568"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213526568" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213526568">(Oct 16 2020 at 07:28)</a>:</h4>
<p>But I like the vocabulary aspect of this; if we have a stable way to describe restricted validity types and let it propagate into the ecosystem than any niche improvements won't be so niche :)</p>



<a name="213549587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213549587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213549587">(Oct 16 2020 at 11:54)</a>:</h4>
<p>We already promise <code>Option&lt;&amp;T&gt;</code> is ABI compatible with a pointer that is either null or valid</p>



<a name="213579923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213579923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213579923">(Oct 16 2020 at 16:04)</a>:</h4>
<p>Yeah but that would be easier for a new implementation to special case than to implement general niche optimization.</p>



<a name="213579934"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213579934" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213579934">(Oct 16 2020 at 16:05)</a>:</h4>
<p>I'd be fine with not making guarantees personally, as long as it's tested to work in rustc in release mode.</p>



<a name="213594098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213594098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213594098">(Oct 16 2020 at 18:01)</a>:</h4>
<p>I think I'd want to see where people end up <em>wanting</em> it as a guarantee.  IIRC people have wanted to do things like <code>Result&lt;Positive32, Negative32&gt;</code> in FFI (<code>HRESULT</code>).  And then we could talk about tradeoffs between general guarantees vs more specific cases, or whether these are better done with other features (like custom patterns, or...)</p>



<a name="213625994"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213625994" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213625994">(Oct 17 2020 at 00:06)</a>:</h4>
<p>I've wanted an <code>IsOddN</code> for 32 and 64 before</p>



<a name="213626762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213626762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213626762">(Oct 17 2020 at 00:27)</a>:</h4>
<p>We can't layout optimize based on that today.</p>



<a name="213630410"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213630410" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213630410">(Oct 17 2020 at 02:01)</a>:</h4>
<p>well you asked what people wanted ;P</p>



<a name="213632084"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213632084" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213632084">(Oct 17 2020 at 02:54)</a>:</h4>
<p>We're also going to have positive values mean success and negatives ones mean errors, but it will always be a status of some kind.</p>
<p>If we're expanding the wish list, it would be cool (but challenging) to represent the entire status space with enums. We'd need to have some support for unrecognized values in enums (e.g. new error codes), while still bounding the set of possible values. We <em>might</em> even want to specify a particular layout for embedded integers (say, values 128-256 are all encoded as variant <code>Status::RemainingToRead(RangedU8&lt;1, 129&gt;)</code>).</p>
<p>Otherwise we'll just represent it as a newtype'd ranged integer with helper methods. That would still fulfill the constraint of letting application code wrap a status in its own ADTs without increasing the size of the type.</p>



<a name="213633837"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213633837" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213633837">(Oct 17 2020 at 03:55)</a>:</h4>
<p>I feel like some of these cases are better handled with some sort of custom pattern support, rather than fitting them into layout optimizations.</p>



<a name="213656678"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213656678" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213656678">(Oct 17 2020 at 15:23)</a>:</h4>
<p><code>IsOddN</code> can be a newtype around <code>NonZeroN</code> to get one niche, at least, while the compiler only deals with contiguous niche ranges.</p>



<a name="213656727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213656727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213656727">(Oct 17 2020 at 15:24)</a>:</h4>
<p><code>IsEvenN</code> can do the same wrapping something like <code>!x</code> or <code>x^1</code></p>



<a name="213698391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213698391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213698391">(Oct 18 2020 at 09:40)</a>:</h4>
<p>besides supporting more niches in the compiler and letting the user define niches, there are also some open issues around using our existing niches better</p>



<a name="213698409"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213698409" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213698409">(Oct 18 2020 at 09:41)</a>:</h4>
<p>primarily, <a href="https://github.com/rust-lang/rust/issues/46213">https://github.com/rust-lang/rust/issues/46213</a></p>



<a name="213698548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213698548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213698548">(Oct 18 2020 at 09:44)</a>:</h4>
<p>While I don't think we are in a position to actually improve this right now, I would like to see (1) nested enums sharing a tag field (2) multiple tags or bools stuffed into one byte, for example <code>sizeof::&lt;Option&lt;Result&lt;(bool, (), bool), bool&gt;&gt;&gt;() == 1</code>, supported using write-back for references.</p>



<a name="213698630"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213698630" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213698630">(Oct 18 2020 at 09:46)</a>:</h4>
<p>I don't know if we would ever want to <em>promise</em> such complex layouts though</p>



<a name="213698774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213698774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213698774">(Oct 18 2020 at 09:50)</a>:</h4>
<p>The logical endpoint of this is of course "entropy encoding", where you count up the number of possible values of the type and stuff them into the minimum number of bytes that have that many values. Clearly a pipe dream, but still an interesting thought experiment</p>



<a name="213701517"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213701517" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213701517">(Oct 18 2020 at 11:04)</a>:</h4>
<blockquote>
<p>write-back for references</p>
</blockquote>
<p>I think that's not possible... too much code already assumes how "writing to a mutable ref" works, e.g. <code>mem::swap</code></p>



<a name="213701525"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213701525" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213701525">(Oct 18 2020 at 11:04)</a>:</h4>
<p>such things are only possible with "no-reference" fields I think</p>



<a name="213701530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213701530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213701530">(Oct 18 2020 at 11:04)</a>:</h4>
<p>but it'd be great to have them that way!</p>



<a name="213701872"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213701872" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213701872">(Oct 18 2020 at 11:14)</a>:</h4>
<p>Actually, it seems like we could write a <code>WriteBack&lt;T&gt;</code> even today, like so (sprinkle <code>unsafe</code> to taste):</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">struct</span> <span class="nc">WriteBack</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">PhantomData</span><span class="o">&lt;&amp;'</span><span class="na">a</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="p">);</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">ptr</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">WriteBack</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="bp">Self</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">,</span><span class="w"> </span><span class="n">ptr</span><span class="p">,</span><span class="w"> </span><span class="n">PhantomData</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DerefMut</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">deref_mut</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">Drop</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="mi">1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>This doesn't work for all types, in particular anything that needs to be Pin, but as long as you can move the type it seems like a trick like this can be used to extract a field and present a uniform interface as a <code>&amp;mut bool</code> or whatever, packing the result when the <code>WriteBack</code> is dropped</p>



<a name="213702328"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702328" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702328">(Oct 18 2020 at 11:28)</a>:</h4>
<p>That needs <code>ManuallyDrop</code> for the first field and <code>std::ptr::write</code> in the drop impl and even then it doesn't prevent things like the following:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">wb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">WriteBack</span>::<span class="n">new</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="p">);</span><span class="w"></span>
<span class="o">*</span><span class="n">wb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span><span class="w"> </span><span class="c1">// first drop of `a`</span>
<span class="n">std</span>::<span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">wb</span><span class="p">);</span><span class="w"></span>
<span class="n">std</span>::<span class="n">mem</span>::<span class="nb">drop</span><span class="p">(</span><span class="n">a</span><span class="p">);</span><span class="w"> </span><span class="c1">// second drop of `a`</span>
</code></pre></div>



<a name="213702460"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702460" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702460">(Oct 18 2020 at 11:32)</a>:</h4>
<p>What's the <code>ManuallyDrop</code> for? After the <code>drop</code> function runs, <code>self.0</code> should be moved out of</p>



<a name="213702496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702496">(Oct 18 2020 at 11:34)</a>:</h4>
<p>or maybe that just wouldn't compile, and the replacement that does (<code>ptr::write</code>) doesn't have the moved out behavior?</p>



<a name="213702616"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702616" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702616">(Oct 18 2020 at 11:38)</a>:</h4>
<blockquote>
<p>or maybe that just wouldn't compile</p>
</blockquote>
<p>Correct drop takes <code>&amp;mut self</code>, so you can't move out of it.</p>
<blockquote>
<p>and the replacement that does (ptr::write) doesn't have the moved out behavior?</p>
</blockquote>
<p>That one doesn't behave differently wrt <code>self.0</code> it only prevents <code>*self.1</code> from getting dropped, as you moved it in <code>new</code>. (that one needs to use <code>std::ptr::read</code> by the way, as <code>*ptr</code> only works for <code>Copy</code> types)</p>



<a name="213702672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702672">(Oct 18 2020 at 11:39)</a>:</h4>
<p>yeah, I'm writing in C style rust for sketch purposes</p>



<a name="213702758"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702758" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702758">(Oct 18 2020 at 11:41)</a>:</h4>
<p>but the drop issue is a big problem; I suspected something like that would happen from the guaranteed destructors thread. If this were part of an advanced enum optimization, I would expect the compiler/borrow checker to be tracking these specially, such that <code>forget</code> actually runs the drop impl instead</p>



<a name="213702827"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213702827" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213702827">(Oct 18 2020 at 11:43)</a>:</h4>
<p>We are back at <code>Drop</code> alone not being a reliable scoping pattern. But with a callback that pattern would work:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span>::<span class="n">core</span>::<span class="n">mem</span>::<span class="n">ManuallyDrop</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="cm">/* House */</span><span class="w"> </span><span class="n">MD</span><span class="p">;</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">WriteBack</span><span class="o">&lt;'</span><span class="na">a</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">MD</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">PhantomData</span><span class="o">&lt;&amp;'</span><span class="na">a</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="p">);</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">with_new</span><span class="o">&lt;</span><span class="n">R</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ptr</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">with</span>: <span class="nc">F</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="w"></span>
<span class="w">  </span><span class="k">where</span><span class="w"></span>
<span class="w">    </span><span class="n">F</span><span class="w"> </span>: <span class="nb">FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="p">,</span><span class="w"></span>
<span class="w">  </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">ptr</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">with</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">Self</span><span class="p">(</span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">ptr</span><span class="p">.</span><span class="n">read</span><span class="p">()</span><span class="w"> </span><span class="p">}.</span><span class="n">into</span><span class="p">(),</span><span class="w"> </span><span class="n">ptr</span><span class="p">,</span><span class="w"> </span><span class="n">PhantomData</span><span class="p">))</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">DerefMut</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">deref_mut</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">Drop</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">WriteBack</span><span class="o">&lt;'</span><span class="nb">_</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">drop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="mf">1.</span><span class="n">write</span><span class="p">(</span><span class="n">MD</span>::<span class="n">take</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="p">))</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="213703002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703002">(Oct 18 2020 at 11:48)</a>:</h4>
<p>wait, with that version does it even need to be a Drop impl? You could just call <code>with</code> and then write back after the function call</p>



<a name="213703009"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703009" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703009">(Oct 18 2020 at 11:48)</a>:</h4>
<p>That could work. I tried to think of a way that <code>std::mem::swap(&amp;mut wb1, &amp;mut wb2)</code> could be misused, but I can't find any way.</p>



<a name="213703010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703010">(Oct 18 2020 at 11:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/layout.20optimization.20in.20stable.3F/near/213703002">said</a>:</p>
<blockquote>
<p>wait, with that version does it even need to be a Drop impl? You could just call <code>with</code> and then write back after the function call</p>
</blockquote>
<p>It does need it because of <code>panic!()</code>.</p>



<a name="213703077"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703077" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703077">(Oct 18 2020 at 11:50)</a>:</h4>
<p>I was wondering about that as well. If we <code>panic!</code>, there are lots of invariants that could be broken, certainly anything relying on a Drop impl, and so catching panics is very restricted. I was hoping that would be sufficient to skip the write back</p>



<a name="213703157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703157">(Oct 18 2020 at 11:52)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span><span class="w"></span>
<span class="n">std</span>::<span class="n">panic</span>::<span class="n">catch_unwind</span><span class="p">(</span><span class="n">std</span>::<span class="n">panic</span>::<span class="n">AssertUnwindSafe</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">WriteBack</span>::<span class="n">with_new</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">panic</span><span class="o">!</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="p">});</span><span class="w"> </span><span class="c1">// first drop in the drop glue of `WriteBack`</span>
<span class="p">});</span><span class="w"></span>
<span class="n">std</span>::<span class="n">mem</span>::<span class="nb">drop</span><span class="p">(</span><span class="n">a</span><span class="p">);</span><span class="w"> </span><span class="c1">// second drop</span>
</code></pre></div>



<a name="213703239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703239">(Oct 18 2020 at 11:54)</a>:</h4>
<p>wait, why is <code>AssertUnwindSafe</code> not unsafe?</p>



<a name="213703297"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703297" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703297">(Oct 18 2020 at 11:57)</a>:</h4>
<p><code>UnwindSafe</code> only exists to prevent breaking logic invariants. It is not for preventing UB when unwinding. I believe there have even been calls to completely remove the <code>UnwindSafe</code> trait.</p>



<a name="213703492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213703492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213703492">(Oct 18 2020 at 12:03)</a>:</h4>
<p>This thread shows there are interests in the subject but that there are different complexity level needed by different use case. Personally I think it would be great to have some sort of basic layout optimization support in stable, around valid/invalid values as discussed early in the thread.</p>



<a name="213706092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213706092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213706092">(Oct 18 2020 at 13:18)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/layout.20optimization.20in.20stable.3F/near/213703002">said</a>:</p>
<blockquote>
<p>wait, with that version does it even need to be a Drop impl? You could just call <code>with</code> and then write back after the function call</p>
</blockquote>
<p>You could simplify that to a <code>: FnOnce(&amp;mut T)</code> callback, and have <code>WriteBack</code> constituents (the separate <code>MD&lt;T&gt;</code> instance, and the <code>*mut T</code>) as function locals, but you'd always need a drop-pable or to <code>catch_unwind(); cleanup; resume_unwind()</code> to be unwind-safe. For that task, <a href="https://docs.rs/scopeguard">https://docs.rs/scopeguard</a> can be quite handy:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">with_write_back</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="o">&gt;</span><span class="w"> </span><span class="p">(</span><span class="n">ptr</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="nc">mut</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">with</span>: <span class="nc">F</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="w"></span>
<span class="k">where</span><span class="w"></span>
<span class="w">    </span><span class="n">F</span><span class="w"> </span>: <span class="nb">FnOnce</span><span class="p">(</span><span class="o">&amp;'</span><span class="nb">_</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="p">,</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">ptr</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">instance</span>: <span class="nc">T</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">ptr</span><span class="p">.</span><span class="n">read</span><span class="p">()</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">instance_with_drop</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>::<span class="n">scopeguard</span>::<span class="n">guard</span><span class="p">(</span><span class="w"></span>
<span class="w">        </span><span class="c1">// Deref{,Mut}</span>
<span class="w">        </span><span class="n">instance</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="c1">// on drop</span>
<span class="w">        </span><span class="o">|</span><span class="n">instance</span><span class="o">|</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">ptr</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">instance</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="p">},</span><span class="w"></span>
<span class="w">    </span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">with</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="n">instance_with_drop</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="213706794"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213706794" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213706794">(Oct 18 2020 at 13:37)</a>:</h4>
<p>Of course the present version, where you trade a <code>&amp;mut T</code> for another <code>&amp;mut T</code> is kind of useless; the real power of this is that the input to the write_back can be a getter/setter pair instead of a <code>&amp;mut T</code>. In the enum optimization case that would be the pack/unpack functions for extracting a field from a densely packed type like a bitfield</p>



<a name="213706885"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/layout%20optimization%20in%20stable%3F/near/213706885" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/layout.20optimization.20in.20stable.3F.html#213706885">(Oct 18 2020 at 13:39)</a>:</h4>
<p>Yes, I think we can agree that <code>&amp;mut T -&gt; &amp;mut T</code> is not the most interesting transformation <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span>, but a more advanced <code>&amp;mut LayoutOptimizedOuter -&gt; &amp;mut Inner</code> using this pattern could indeed be useful <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>